package org.news.web.controller.app;

import cn.dev33.satoken.annotation.SaIgnore;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.dtflys.forest.annotation.Get;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import org.dromara.common.core.domain.R;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.news.web.constant.CategoriesConstant;
import org.news.web.domain.Categories;
import org.news.web.domain.News;
import org.news.web.domain.bo.NewsBo;
import org.news.web.domain.vo.CategoriesVo;
import org.news.web.domain.vo.IndexVo;
import org.news.web.domain.vo.NewsVo;
import org.news.web.mapper.CategoriesMapper;
import org.news.web.mapper.NewsMapper;
import org.news.web.service.ICategoriesService;
import org.news.web.service.INewsService;
import org.news.web.service.IRecommendService;
import org.news.web.utils.UserInfoInterceptorUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;

@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/app/recommend")
@SaIgnore
public class RecommendNewsController {


    private final INewsService newsService;
    private final IRecommendService recommendService;

    private final CategoriesMapper categoriesMapper;

    private final ICategoriesService categoriesService;


    private final NewsMapper newsMapper;


    /**
     * 基于用户的协调过滤推荐新闻
     */
    @GetMapping("/getRecommend")
    public R<List<NewsVo>> getRecomend(HttpServletRequest request){
        Boolean flag = UserInfoInterceptorUtils.CheckUserInfoKey(request);
        String authorization = request.getHeader("Authorization");
        if(flag){
//            给用户进行个性化推荐
            List<NewsVo> recommed = recommendService.getRecommed(authorization);
            return R.ok(recommed);
        }else{
//            当是游客进行访问时
//            随机获取一些新闻内容
            return R.ok(recommendService.RandomNews());
        }
    }

    @GetMapping("/test")
    public R<Void> test(){
        return R.ok();
    }

    /**
     * 基于关键字匹配 新闻的相关新闻
     */
    @GetMapping("/getRelateNews/{newId}")
    public R<List<NewsVo>> getRelateNews(@PathVariable Long newId){
        return R.ok(newsService.getRelateNews(newId));
    }

    /**
     * 基于热门排行榜获取前50排行榜新闻内容
     */
    @GetMapping("/getHot")
    public R<List<NewsVo>> getHot(){
        return R.ok(newsService.getHot());
    }

    /**
     * 获取最新新闻
     */
    @GetMapping("/getNow")
    public TableDataInfo<NewsVo> getNow(NewsBo bo, PageQuery pageQuery){
        return newsService.getNow(bo,pageQuery);
    }


    /**
     * 获取每个类别的新闻信息
     */
    @GetMapping("/indexInfo")
    public R<List<IndexVo>> indexInfo(){
        // todo 缓存
        //获取所有顶级类别的信息
        List<CategoriesVo> categoriesVos = categoriesMapper.selectVoList(new LambdaQueryWrapper<Categories>().eq(Categories::getStatus, CategoriesConstant.StatusLb()).eq(Categories::getParentCategoryId,0));

        if(categoriesVos == null || categoriesVos.size() == 0){
            return R.fail("数据异常!");
        }
//        通过这些信息获取6个最近的新闻信息
        ArrayList<IndexVo> indexVos = new ArrayList<>();
        categoriesVos.forEach(
            categoriesVo -> {
                IndexVo indexVo = new IndexVo();
                indexVo.setCategoriesVo(categoriesVo);
                // 通过类别获取新闻
                // 获取当前类别下的所有子节点id
                List<Long> ids = categoriesService.getLBListChild(Math.toIntExact(categoriesVo.getCategoryId()));
                // 设置条件
                PageQuery pageQuery = new PageQuery();
                pageQuery.setIsAsc("desc");
                pageQuery.setOrderByColumn("publishTime");
                pageQuery.setPageNum(1);
                pageQuery.setPageSize(6);

                IPage<NewsVo> newsVoIPage = newsMapper.selectVoPage(pageQuery.build(), new LambdaQueryWrapper<News>().in(News::getCategories, ids));
                // 设置name 和 url
                newsService.setNewsImg(newsVoIPage.getRecords());
                newsService.setNewsAuthorName(newsVoIPage.getRecords());

                indexVo.setNewsVoList(newsVoIPage.getRecords());
                indexVos.add(indexVo);
            }
        );

        return R.ok(indexVos);
    }



}
